package edu.hawaii.stack;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
// atshum: Eclipse suggested removing line below since never used
// import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * Test case for the Stack abstract data type, which checks to see that you can push three
 * objects onto the stack, then pop them off and get the exact same objects in the correct order.
 * This test also checks to see that popping an empty stack generates an exception.
 *
 * @author Philip Johnson
 * @version $Id: TestStack.java,v 1.6 2004/10/27 22:58:03 johnson Exp $
 */
public class TestStack {

  // Objects used for testing.
  private final Integer one = Integer.valueOf(1);
  private final Integer two = Integer.valueOf(2);
  private final Integer three = Integer.valueOf(3);
// atshum: replaced below with above
// private Integer one = new Integer(1);
// private Integer two = new Integer(2);
// private Integer three = new Integer(3);
  
  /**
   * Test normal stack push.
   *
   * @exception EmptyStackException If errors during stack processing.
   */
  @Test 
  public void testNormalOperation() throws EmptyStackException {
    Stack stack = new Stack();
    stack.push(one);
    stack.push(two);
    stack.push(three);
    assertEquals("Testing stack asArray", 3, stack.toArray().length);
    assertSame("Testing stack top of three", three, stack.top());
    assertSame("Testing stack pop of three", three, stack.pop());
    assertSame("Testing stack pop of two", two, stack.pop());
    assertSame("Testing stack pop of one", one, stack.pop());
// atshum: replaced below with above    
//  assertSame("Testing stack pop of three", two, stack.pop());
  }

// atshum: commented out try, fail, catch statements
// atshum: modified @Test statement to use JUnit 4 exception annotation
// atshum: Eclipse suggested adding throws clause to method signature
// atshum: added @throws statement in Javadoc 
  /** Test illegal pop of empty stack.  Should use JUnit 4 exception annotation!
   * @throws EmptyStackException If the stack is empty.
   */
//@Test
//public void testIllegalPop() {  
  @Test(expected = EmptyStackException.class)
  public void testIllegalPop() throws EmptyStackException {
    Stack stack = new Stack();
//  try {
      stack.pop();
//    fail("Pop of empty stack did not generate exception.");
//  }
//  catch (EmptyStackException e) {
      // shouldn't get here. 
//  }
  }
  
// atshum: added below to get 100% coverage.
  /**
   * Test toString method.
   */
  @Test
  public void testToString() {
    Stack stack = new Stack();
    stack.push(one);
    stack.push("hello");
    stack.push(true);
    // Create another stack to push into the first stack.
    Stack substack = new Stack();
    substack.push(3.14);
    substack.push("goodbye");
    stack.push(substack);
    String expectedString = "[Stack [1, hello, true, [Stack [3.14, goodbye]]]]";
    assertEquals("Testing toString", expectedString, stack.toString());
  }
  
}
